package com.ktgj.customer.util;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Enumeration;

/**
 * Created by chengshifei on 2019/7/11.
 */
public class RsaUtil {

    static final Log log = LogFactory.getLog(RsaUtil.class);

    public static String encryptByPriPfxStream(String src, byte[] pfxBytes, String priKeyPass) {
        PrivateKey privateKey = getPrivateKeyByStream(pfxBytes, priKeyPass);
        return privateKey == null?null:encryptByPrivateKey(src, privateKey);
    }
    public static String encryptByPrivateKey(String src, PrivateKey privateKey) {
        byte[] destBytes = rsaByPrivateKey(src.getBytes(), privateKey, 1);
        return destBytes == null?null:StringUtil.byte2Hex(destBytes);
    }
    public static byte[] rsaByPrivateKey(byte[] srcData, PrivateKey privateKey, int mode) {
        try {
            Cipher e = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            e.init(mode, privateKey);
            int blockSize = mode == 1?117:128;
            byte[] decryptData = null;

            for(int i = 0; i < srcData.length; i += blockSize) {
                byte[] doFinal = e.doFinal(ArrayUtils.subarray(srcData, i, i + blockSize));
                decryptData = ArrayUtils.addAll(decryptData, doFinal);
            }

            return decryptData;
        } catch (NoSuchAlgorithmException var8) {
            log.error("私钥算法-不存在的解密算法:", var8);
        } catch (NoSuchPaddingException var9) {
            log.error("私钥算法-无效的补位算法:", var9);
        } catch (IllegalBlockSizeException var10) {
            log.error("私钥算法-无效的块大小:", var10);
        } catch (BadPaddingException var11) {
            log.error("私钥算法-补位算法异常:", var11);
        } catch (InvalidKeyException var12) {
            log.error("私钥算法-无效的私钥:", var12);
        }

        return null;
    }
    public static PrivateKey getPrivateKeyByStream(byte[] pfxBytes, String priKeyPass) {
        try {
            KeyStore e = KeyStore.getInstance("PKCS12");
            char[] charPriKeyPass = priKeyPass.toCharArray();
            e.load(new ByteArrayInputStream(pfxBytes), charPriKeyPass);
            PrivateKey prikey = null;
            Enumeration aliasEnum = e.aliases();
            String keyAlias = null;

            while(aliasEnum.hasMoreElements()) {
                keyAlias = (String)aliasEnum.nextElement();
                prikey = (PrivateKey)e.getKey(keyAlias, charPriKeyPass);
                if(prikey != null) {
                    break;
                }
            }

            return prikey;
        } catch (IOException var7) {
            log.error("解析文件，读取私钥失败:", var7);
        } catch (KeyStoreException var8) {
            log.error("私钥存储异常:", var8);
        } catch (NoSuchAlgorithmException var9) {
            log.error("不存在的解密算法:", var9);
        } catch (CertificateException var10) {
            log.error("证书异常:", var10);
        } catch (UnrecoverableKeyException var11) {
            log.error("不可恢复的秘钥异常", var11);
        }

        return null;
    }

    /**
     * 解密
     * @param src
     * @param pubKeyText
     * @return
     */
    public static String decryptByPubCerText(String src, String pubKeyText) {
        PublicKey publicKey = getPublicKeyByText(pubKeyText);
        return publicKey == null?null:decryptByPublicKey(src, publicKey);
    }
    public static String decryptByPublicKey(String src, PublicKey publicKey) {
        try {
            byte[] e = rsaByPublicKey(StringUtil.hex2Bytes(src), publicKey, 2);
            return e == null?null:new String(e, "UTF-8");
        } catch (UnsupportedEncodingException var3) {
            log.error("解密内容不是正确的UTF8格式:", var3);
            return null;
        }
    }
    public static PublicKey getPublicKeyByText(String pubKeyText) {
        try {
            CertificateFactory e = CertificateFactory.getInstance("X509");
            BufferedReader br = new BufferedReader(new StringReader(pubKeyText));
            String line = null;
            StringBuilder keyBuffer = new StringBuilder();

            while((line = br.readLine()) != null) {
                if(!line.startsWith("-")) {
                    keyBuffer.append(line);
                }
            }

            java.security.cert.Certificate certificate = e.generateCertificate(new ByteArrayInputStream(Base64Util.decode2bytes(keyBuffer.toString())));
            return certificate.getPublicKey();
        } catch (Exception var6) {
            log.error("解析公钥内容失败:", var6);
            return null;
        }
    }
    public static byte[] rsaByPublicKey(byte[] srcData, PublicKey publicKey, int mode) {
        try {
            Cipher e = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            e.init(mode, publicKey);
            int blockSize = mode == 1?117:128;
            byte[] encryptedData = null;

            for(int i = 0; i < srcData.length; i += blockSize) {
                byte[] doFinal = e.doFinal(ArrayUtils.subarray(srcData, i, i + blockSize));
                encryptedData = ArrayUtils.addAll(encryptedData, doFinal);
            }

            return encryptedData;
        } catch (NoSuchAlgorithmException var8) {
            log.error("公钥算法-不存在的解密算法:", var8);
        } catch (NoSuchPaddingException var9) {
            log.error("公钥算法-无效的补位算法:", var9);
        } catch (IllegalBlockSizeException var10) {
            log.error("公钥算法-无效的块大小:", var10);
        } catch (BadPaddingException var11) {
            log.error("公钥算法-补位算法异常:", var11);
        } catch (InvalidKeyException var12) {
            log.error("公钥算法-无效的私钥:", var12);
        }

        return null;
    }
}
